import datetime
import os

from fastapi import requests, HTTPException
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langsmith import traceable

from common.logger_util import logger
from server.openai_chain_server import create_chain_server
from server.openai_graph_server import create_graph_server
from translate import Translator
import requests

ai_server_instance = create_chain_server()
graph_instance = create_graph_server()
# Specify an ID for the thread
config_json = {"configurable": {"thread_id": "LuckyZhou", "session_id": "LuckyZhou"}}

def stream_gpt_and_return_str_response(messages: [], return_response):
    contents = ""
    for i in ai_server_instance.llm.astream(messages):
        print("---------------------")
        print(i.content, end='')
        contents += i.content
        yield i.content
        return_response.append(i.content)


def handle_user_input(user_input):
    # 查询知识库
    docs = ai_server_instance.qa_chain.invoke(user_input)
    return docs


def response_chain_stream(user_input):
    # 查询知识库
    for content in ai_server_instance.qa_chain.stream(user_input):
        yield content


@traceable # Auto-trace this function
def response_with_agent_history(user_id, user_input):
    for step in ai_server_instance.agent_with_chat_history.stream({"user_id": user_id, "input": user_input}, config=config_json, ):
        logger.debug(step)
        print(step)
        # Extract the content from the first AIMessage in the messages array
        # Check if 'output' is in the step and if it contains 'messages'
        if 'output' in step and 'messages' in step:
            messages = step['messages']
            if messages and isinstance(messages[0], AIMessage):
                # Yield the content of the first AIMessage
                yield messages[0].content

@traceable
def response_with_graph_agent_history(user_id, user_input):
    try:
        for step in graph_instance.graph.stream(
                {"messages": [HumanMessage(content=user_input, additional_kwargs={"user_id": user_id})]},
                config=config_json,
                stream_mode="values",
        ):
            if "messages" in step and step["messages"]:
                message = step["messages"][-1]

                # 检查是否是工具返回的结果
                if isinstance(message, ToolMessage):
                    content = message.content
                    if isinstance(content, str) and "result" in content:
                        # 如果是有效的结果，直接返回
                        yield content
                        return

                # 检查是否是AI的回复
                elif isinstance(message, AIMessage) and message.content:
                    yield message.content
                    return
    except Exception as e:
        logger.error(f"Error: {str(e)}")
        yield f"处理请求时出现错误: {str(e)}"


def translate_text(text: str, to_lang: str = 'en') -> str:
    """
    简单的中英互译函数
    参数:
        text: 要翻译的文本
        to_lang: 目标语言 ('en'为英语, 'zh'为中文)
    返回:
        翻译后的文本
    """
    try:
        # 根据目标语言设置源语言
        from_lang = 'zh' if to_lang == 'en' else 'en'

        # 创建翻译器
        translator = Translator(from_lang=from_lang, to_lang=to_lang)

        # 执行翻译
        result = translator.translate(text)
        return result

    except Exception as e:
        print(f"翻译错误: {e}")
        return text  # 发生错误时返回原文


def get_file_name(file_path: str) -> str:
    return translate_text(file_path, 'en').replace(" ", "_") + "_" + datetime.datetime.now().strftime(
        "%Y%m%d-%H%M%S")


def write2disk(video_url:str, save_path:str, proxy:str = None):
    if not save_path.endswith('/'):
        save_path += '/'
    # 生成文件名（使用时间戳避免重复）
    timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
    video_name = f'video_{timestamp}.mp4'
    save_path = os.path.join(save_path, video_name)

    # 设置代理
    proxies = {}
    if proxy:
        proxies = {
            'http': proxy,
            'https': proxy
        }

    try:
        # 下载视频（使用代理）
        response = requests.get(video_url, stream=True, proxies=proxies, timeout=30)
        if response.status_code == 200:
            with open(save_path, 'wb') as f:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        f.write(chunk)
            return video_name
        else:
            raise HTTPException(status_code=response.status_code, detail=f"视频下载失败: HTTP {response.status_code}")
    except requests.exceptions.RequestException as e:
        raise HTTPException(status_code=500, detail=f"下载视频时发生错误: {str(e)}")